import re
import yaml
from UpdateActiveUserList import updateActiveUserList
import globals
import configfile
from msg import *
from GetAndReplyMessages import get_and_reply_messages
from EvictMessages import evict_messages_for_user
from Reliabiltiy import handle_failure
from Reliabiltiy import check_failure_message
import sys
import time
import copy

def receive_message (mp, message) :

    #print "message received in receive_message() -> %s --- type %s ---- from %s ----  bsrc %s" % (message.data, message.mtype, message.src, message.broadcastSource)

    #print " msg.broadcastSource is : ",
    #print message.broadcastSource

    try :
        globals.globalCV.acquire()
        while globals.globalIsFailureHandled == False :
            #print "Entered Condition Variable Wait"
            #print "Message.src is %s MEssageType %s and broadcast source is %s" % (message.src, message.mtype, message.broadcastSource)
            globals.globalCV.wait()
            #print "Wait over"
    finally :
        globals.globalCV.release()

    table = configfile.getForwardingTable(mp.thisName)
    #print "The forwarding table for node %s is :" % (mp.thisName)
    #print table
    #print "Message.src is %s and broadcast source is %s" % (message.src, table[broadcastSource])

    #print 'Received in receive_message_func : ' + message.src + " of type " + message.mtype

    if message.mtype == 'check_in_nodes' or message.mtype == 'check_out_nodes' :
        #print "Message RECEIVED from %s for updating the list " % (message.src)
        if message.broadcastSource != mp.thisName :
            #print "Forwarding table : ",
            #print table[message.broadcastSource]
            if message.src == table[message.broadcastSource] :
                #print "Message accepted from %s for updating the list " % (message.src)
                updateActiveUserList(mp, message)
                #print "after if in receivemessage"
        return

    elif message.mtype == 'cache' :

        femsg = yaml.load(message.data)
     #   print 'Received cache message! fromUserName [%s] toUserName [%s] messageText [%s]' % (femsg.fromUserName, femsg.toUserName, femsg.messageText)
        # Cache the message for replication
        globals.globalCacheMessageList.append(femsg)
        return

    elif message.mtype == 'get_message_for_user' :
        #print "Received get_message_for_user [%s] from node [%s]" % (message.data, message.src)
        if message.broadcastSource != mp.thisName :
            temp=message.data.split(',')
            user = temp[0]
            userGroup=temp[1]
            if message.src == table[message.broadcastSource] :
                temp = message.clone()
                returnList = get_and_reply_messages(mp, temp)
                #print 'In IF part for message from : ' + message.src
            else :
                returnList = None
                #print 'In else part returned None for messgae from : ' + message.src
            if returnList == False :
                return
            data = yaml.dump(returnList)
            msg = Message(mp.thisName, message.src, None, data, 'set_message_for_' + user, mp.thisName)
            #print 'Sent a message to %s from %s of type set_message_for_user' % (message.src, mp.thisName)
            mp.send(msg)
        return

    elif message.mtype.find("set_message_for_") != -1 :

        #print 'Received set_message_for_user from : ' + message.src + ' data: ' + message.data
        if message.broadcastSource != mp.thisName :
            try:
                globals.globalWaitListLock.acquire()
                #print "Message appended"
                globals.globalWaitMessageList.append(message)
                print globals.globalWaitMessageList
            finally :
                globals.globalWaitListLock.release()
        return

    elif  message.mtype == 'evict_messages' :
        if message.broadcastSource != mp.thisName :
            if message.src == table[message.broadcastSource] :
                #print 'Received evict message from : ' + message.src + ' data: ' + message.data
                user = message.data
                evict_messages_for_user(mp, message, user)

    elif message.mtype == 'config' :
        #print "Message RECEIVED FOR LOADING NEW YAML "
        data = yaml.load(message.data)
        print data

        configfile.comGraph[data['name']] = copy.deepcopy(data['group'])

        print configfile.comGraph
        for item in data['group'] :

            print item
            if item != data['name'] :
                configfile.comGraph[item].append(data['name'])
        #print "Graph after reconstruction is : ",
        #print configfile.comGraph
        #print ""

    elif message.mtype == 'node_failure' :


        if check_failure_message (message) == True :

            globals.globalIsFailureHandled = False
            #globalShutdownLock.acquire()
            globals.globalShutdown = True
            #globalShutdownLock.release()
            #time.sleep(0.05)
            #print "Global shutdown var : ",
            #print globalShutdown
            print "**GLOBAL _ SHUTDOWN **"
            #sys.exit(1)
            try :
                globals.globalCV.acquire()
                handle_failure (mp, message)
                globals.globalIsFailureHandled = True
                globals.globalCV.notify_all()
                #print "Notified threads"
            finally :
                #print "CV Lock released"
                globals.globalCV.release()

            if globals.globalGetMessageRequests == 0 :
                try :
                    globals.globalShutdownLock.acquire()
                    print "**GLOBAL _ SHUTDOWN _ TURNED _ OFF**"
                    globals.globalShutdown = False
                finally :
                    globals.globalShutdownLock.release()
    return
